<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>

</body>
<script>

    // 作用域：变量能够访问到的范围
    // 全局作用域：任何不在函数中或大括号中声明的变量，都是在全局作用域下。全局作用域下声明的变量可以在程序的任意位置访问到
    // 函数作用域：如果一个变量在函数内部声明的，它就是在函数作用域下，这些变量只能在函数内部访问，不能再函数以外访问
    // 块级作用域：ES6引入了let和const关键字，在大括号中使用let和const声明的变量存在于块级作 用域中，在大括号外不能被访问
    // var a = 18;
    // function fn1() {
    //     var a = 21;
    //     function fn2() {
    //         console.log(a)
    //     }
    //     return fn2()
    // }
    // fn1();
    // 作用域链
    //  当我们在查找一个一个变量时，先在函数中查找，如果没有找到，再去去外层作用域中查找，有个
    // 往外层查找的过程，我们就好像是顺着一条链条从里往外查找变量，这条连链条，我们称之为作用域
    // 链。

    // var a = 1;
    // function fn1() {
    //     var b = 2;
    //     function fn2() {
    //         var c = 3;
    //         function fn3() {
    //             var d = 4;
    //             function fn4() {
    //                 var e = 5;
    //             }
    //             fn4()
    //         }
    //         fn3()
    //     }
    //     fn2()
    // }
    // fn1()


    // // 问题：
    // // 打印函数say的结构
    // console.log(say);
    // var say = '123';
    // function say() {
    //     console.log('456');
    // }
    // // 打印变量say
    // console.log(say);
    // // 因为函数声明覆盖了变量声明，而变量的初始化发生在函数声明之后



    // 闭包:跨作用域访问变量，延长变量作用域的生命周期
    // 闭包的形式，1.函数内部返回一个变量2.函数内部返回一个函数
    // function fn(){
    //     var a = 18;
    //     return a
    // }
    // console.log(fn());    
    // 闭包
    // function fn() {
    //     var a = 1;
    //     return function () {
    //         console.log(a);
    //     }
    // }
    // console.dir(fn());
    // 闭包案例
    // var a = 10;
    // function fn() {
    //     var a = 20;
    //     function fn2() {
    //         console.log(a);

    //     }；
    //     fn(fn2);
    // }
    // function fn2() {
    //     fn();
    // }
    // fn2();
    // 经典的闭包：IIFE







</script>

</html>